#ifndef VM_PAGE_H
#define VM_PAGE_H

#include <hash.h>
#include "threads/thread.h"

/* Location of a page. */
enum page_location {
    MEMORY,   // The page is in memory.
    SWAP,     // The page is in the swap partition.
    FILE      // The page is in a file.
};

/* Supplemental page table entry structure. */
struct spte {
    void *upage;                  // User virtual address.
    void *kpage;                  // Kernel physical address (if loaded).
    enum page_location location;  // Location of the page.
    bool writable;                // Is the page writable?
    size_t swap_index;            // Index in the swap partition (if applicable).
    struct hash_elem hash_elem;   // Hash table element.
};

/* Supplemental page table structure. */
struct supplemental_page_table {
    struct hash page_hash;        // Hash table storing supplemental page table entries.
};

/* Initializes a supplemental page table. */
void supplemental_page_table_init(struct supplemental_page_table *spt);

/* Destroys a supplemental page table and frees all resources. */
void supplemental_page_table_destroy(struct supplemental_page_table *spt);

/* Inserts a page into the supplemental page table. */
bool supplemental_page_table_insert(struct supplemental_page_table *spt, void *upage, void *kpage, bool writable);

/* Finds a page in the supplemental page table. */
struct spte *supplemental_page_table_find(struct supplemental_page_table *spt, void *upage);

/* Removes a page from the supplemental page table. */
void supplemental_page_table_remove(struct supplemental_page_table *spt, void *upage);

#endif /* vm/page.h */
